﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;
using System.Threading;

namespace PlateNumber {
    public partial class DataForm : Form {
        public DataForm() {
            InitializeComponent();
        }

        private void DataForm_Load(object sender, EventArgs e) {
            LoadTestData();
            LoadFormalData();
            UpdateUI();
        }

        // 载入测试数据
        private void LoadTestData() {
            OleDbDataAdapter da = new OleDbDataAdapter(
                "SELECT * FROM Test",
                Program.ConnectionString);
            DataTable dt = new DataTable();
            using (da) {
                da.Fill(dt);
            }

            dataGridView1.DataSource = dt;
            dataGridView1.ClearSelection();
            tabControl1.TabPages[1].Text = "探测数据(" + dt.Rows.Count + ")";
        }

        // 载入正式数据
        private void LoadFormalData() {
            OleDbDataAdapter da = new OleDbDataAdapter(
                "SELECT * FROM Formal",
                Program.ConnectionString);
            DataTable dt = new DataTable();
            using (da) {
                da.Fill(dt);
            }

            dataGridView2.DataSource = dt;
            dataGridView2.ClearSelection();
            tabControl1.TabPages[0].Text = "正式数据(" + dt.Rows.Count + ")";
        }

        private void dataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) {
            if (tabControl1.SelectedIndex == 1) {
                // 测试
                if (dataGridView1.Columns[e.ColumnIndex].DataPropertyName == "State") {
                    switch ((int)e.Value) {
                        case 1:
                            e.Value = "探测成功";
                            break;
                        case 0:
                            e.Value = "等待预约";
                            break;
                        case -1:
                            e.Value = "今天已无法预约";
                            break;
                        case -2:
                            e.Value = "号牌不存在";
                            break;
                        case -3:
                            e.Value = "号牌已被预约";
                            break;
                    }
                }

                if (dataGridView1.Columns[e.ColumnIndex].DataPropertyName == "SubmitDate" &&
                    String.IsNullOrEmpty(e.Value.ToString())) {
                    e.Value = String.Empty;
                }
            }
            else {
                // 正式
                if (dataGridView2.Columns[e.ColumnIndex].DataPropertyName == "State") {
                    switch ((int)e.Value) {
                        case 1:
                            e.Value = "预约完成";
                            break;
                        case 0:
                            e.Value = "等待预约";
                            break;
                        case -1:
                            e.Value = "今天已无法预约";
                            break;
                        case -2:
                            e.Value = "号牌不存在";
                            break;
                        case -3:
                            e.Value = "号牌已被预约";
                            break;
                    }
                }

                if (dataGridView2.Columns[e.ColumnIndex].DataPropertyName == "SubmitDate" &&
                    String.IsNullOrEmpty(e.Value.ToString())) {
                    e.Value = String.Empty;
                }
            }
        }

        private void dataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e) {
            if (e.RowIndex >= 0) {
                if (tabControl1.SelectedIndex == 1) {
                    // 测试
                    if (e.RowIndex < dataGridView1.Rows.Count &&
                        dataGridView1.Rows[e.RowIndex].Cells["testInvalid"].Value.ToString() == Boolean.TrueString) {
                        e.CellStyle.ForeColor = Color.Red;
                    }
                }
                else {
                    // 正式
                    if (e.RowIndex < dataGridView2.Rows.Count &&
                        dataGridView2.Rows[e.RowIndex].Cells["formalInvalid"].Value.ToString() == Boolean.TrueString) {
                        e.CellStyle.ForeColor = Color.Red;
                    }
                    if (e.RowIndex < dataGridView2.Rows.Count &&
                       dataGridView2.Rows[e.RowIndex].Cells["formalState"].Value.ToString() == "1") {
                        e.CellStyle.ForeColor = Color.Blue;
                    }
                }
            }
        }

        private void dataGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e) {
            btnEdit.PerformClick();
        }

        private void dataGridView_SelectionChanged(object sender, EventArgs e) {
            UpdateUI();
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) {
            UpdateUI();
        }

        private string[] GetPlateNumbers(string pattern) {
            // 1.计算总数
            int[] powers = new int[5];
            for (int i = 0; i < 5; ++i) {
                if (pattern.Substring(i, 1) == "*") {
                    switch (i) {
                        case 0:
                        case 1:
                        case 2:
                            powers[i] = 10; // 0-9
                            break;
                        case 3:
                            powers[i] = 5;  // C、D、E、F
                            break;
                        case 4:
                            powers[i] = 23; // A、B、C、D、E、F、G、H、J、K、L、M、N、P、Q、R、S、T、U、V、W、X、Y
                            break;
                    }
                }
                else {
                    powers[i] = 1;
                }
            }

            int count = 1;
            foreach (int p in powers) {
                count *= p;
            }

            // 2.生成号码
            string[] digit = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
            string[] alpha1 = { "C", "D", "E", "F", "G" };
            string[] alpha2 = { "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y" };
            string[] numbers = new string[count];

            for (int i = 0; i < 5; ++i) {
                int j = 0;

                for (int c = 0; c < numbers.Length; ++c) {
                    if (numbers[c] == null) {
                        numbers[c] = "-----";
                    }

                    if (pattern.Substring(i, 1) == "*") {
                        // 通配符

                        // 计算后续号码数量
                        int nextPowersCount = 1;
                        for (int p = i + 1; p < powers.Length; ++p) {
                            nextPowersCount *= powers[p];
                        }

                        switch (i) {
                            case 0:
                            case 1:
                            case 2:
                                numbers[c] = numbers[c].Substring(0, i) + digit[j] + numbers[c].Substring(i + 1);
                                if (c % nextPowersCount == 0) {
                                    ++j;
                                    if (j >= digit.Length) {
                                        j = 0;
                                    }
                                }
                                break;
                            case 3:
                                numbers[c] = numbers[c].Substring(0, i) + alpha1[j] + numbers[c].Substring(i + 1);
                                if (c % nextPowersCount == 0) {
                                    ++j;
                                    if (j >= alpha1.Length) {
                                        j = 0;
                                    }
                                }
                                break;
                            case 4:
                                numbers[c] = numbers[c].Substring(0, i) + alpha2[j] + numbers[c].Substring(i + 1);
                                if (c % nextPowersCount == 0) {
                                    ++j;
                                    if (j >= alpha2.Length) {
                                        j = 0;
                                    }
                                }
                                break;
                        }

                    }
                    else {
                        // 非通配符
                        numbers[c] = numbers[c].Substring(0, i) + pattern.Substring(i, 1) + numbers[c].Substring(i + 1);
                    }
                } // for
            }
            return numbers;
        }


        // 新建
        private void btnNew_Click(object sender, EventArgs e) {
            DataPropertyForm form = new DataPropertyForm();
            form.Mode = (tabControl1.SelectedIndex == 1 ? (int)FormMode.Test : (int)FormMode.Formal) | (int)FormMode.New;

            if (form.ShowDialog(this) == DialogResult.OK) {
                using (OleDbConnection conn = new OleDbConnection(Program.ConnectionString)) {
                    conn.Open();

                    if (tabControl1.SelectedIndex == 1) {
                        //
                        // 测试
                        //

                        if (form.PlateNumber.IndexOf("*") >= 0) {
                            //
                            // 批量
                            //
                            string[] numbers = GetPlateNumbers(form.PlateNumber);

                            // 3.写数据库
                            foreach (string number in numbers) {
                                using (OleDbCommand cmd = new OleDbCommand("INSERT INTO Test(PlateNumber, SubmitDate, State, Invalid) VALUES(@PlateNumber, @SubmitDate, @State, @Invalid)", conn)) {
                                    cmd.Parameters.AddWithValue("@PlateNumber", number);
                                    if (form.SubmitDate != DateTime.MinValue.Date) {
                                        cmd.Parameters.AddWithValue("@SubmitDate", form.SubmitDate);
                                    }
                                    else {
                                        cmd.Parameters.AddWithValue("@SubmitDate", System.DBNull.Value);
                                    }
                                    cmd.Parameters.AddWithValue("@State", form.State);
                                    cmd.Parameters.AddWithValue("@Invalid", form.Invalid);
                                    cmd.ExecuteNonQuery();
                                }
                            }
                            conn.Close();

                            // 4.更新视图
                            int prevCount = dataGridView1.Rows.Count;
                            LoadTestData();
                            for (int i = prevCount; i < dataGridView1.Rows.Count; ++i) {
                                dataGridView1.Rows[i].Selected = true;
                            }
                            dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.Rows.GetLastRow(DataGridViewElementStates.None);
                        }
                        else {
                            //
                            // 单个
                            //

                            using (OleDbCommand cmd = new OleDbCommand("INSERT INTO Test(PlateNumber, SubmitDate, State, Invalid) VALUES(@PlateNumber, @SubmitDate, @State, @Invalid)", conn)) {
                                cmd.Parameters.AddWithValue("@PlateNumber", form.PlateNumber);
                                if (form.SubmitDate != DateTime.MinValue.Date) {
                                    cmd.Parameters.AddWithValue("@SubmitDate", form.SubmitDate);
                                }
                                else {
                                    cmd.Parameters.AddWithValue("@SubmitDate", System.DBNull.Value);
                                }
                                cmd.Parameters.AddWithValue("@State", form.State);
                                cmd.Parameters.AddWithValue("@Invalid", form.Invalid);
                                cmd.ExecuteNonQuery();
                            }
                            conn.Close();
                        } // 批量 or 单个

                        LoadTestData();
                        dataGridView1.Rows[dataGridView1.Rows.GetLastRow(DataGridViewElementStates.None)].Selected = true;
                        dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.Rows.GetLastRow(DataGridViewElementStates.None);
                    }
                    else {
                        //
                        // 正式
                        //

                        if (form.PlateNumber.IndexOf("*") >= 0) {
                            //
                            // 批量
                            //
                            string[] numbers = GetPlateNumbers(form.PlateNumber);

                            // 3.写数据库
                            foreach (string number in numbers) {
                                using (OleDbCommand cmd = new OleDbCommand("INSERT INTO Formal(VIN, PlateNumber, CardType, CardNo, SubmitDate, State, Invalid) VALUES(@VIN, @PlateNumber, @CardType, @CardNo, @SubmitDate, @State, @Invalid)", conn)) {
                                    cmd.Parameters.AddWithValue("@VIN", form.VIN);
                                    cmd.Parameters.AddWithValue("@PlateNumber", number);
                                    cmd.Parameters.AddWithValue("@CardType", form.CardType);
                                    cmd.Parameters.AddWithValue("@CardNo", form.CardNo);
                                    if (form.SubmitDate != DateTime.MinValue.Date) {
                                        cmd.Parameters.AddWithValue("@SubmitDate", form.SubmitDate);
                                    }
                                    else {
                                        cmd.Parameters.AddWithValue("@SubmitDate", System.DBNull.Value);
                                    }
                                    cmd.Parameters.AddWithValue("@State", form.State);
                                    cmd.Parameters.AddWithValue("@Invalid", form.Invalid);
                                    cmd.ExecuteNonQuery();
                                }
                            }
                            conn.Close();

                            // 4.更新视图
                            int prevCount = dataGridView2.Rows.Count;
                            LoadFormalData();
                            for (int i = prevCount; i < dataGridView2.Rows.Count; ++i) {
                                dataGridView2.Rows[i].Selected = true;
                            }
                            dataGridView2.FirstDisplayedScrollingRowIndex = dataGridView2.Rows.GetLastRow(DataGridViewElementStates.None);
                        }
                        else {
                            //
                            // 单个
                            //

                            using (OleDbCommand cmd = new OleDbCommand("INSERT INTO Formal(VIN, PlateNumber, CardType, CardNo, SubmitDate, State, Invalid) VALUES(@VIN, @PlateNumber, @CardType, @CardNo, @SubmitDate, @State, @Invalid)", conn)) {
                                cmd.Parameters.AddWithValue("@VIN", form.VIN);
                                cmd.Parameters.AddWithValue("@PlateNumber", form.PlateNumber);
                                cmd.Parameters.AddWithValue("@CardType", form.CardType);
                                cmd.Parameters.AddWithValue("@CardNo", form.CardNo);
                                if (form.SubmitDate != DateTime.MinValue.Date) {
                                    cmd.Parameters.AddWithValue("@SubmitDate", form.SubmitDate);
                                }
                                else {
                                    cmd.Parameters.AddWithValue("@SubmitDate", System.DBNull.Value);
                                }
                                cmd.Parameters.AddWithValue("@State", form.State);
                                cmd.Parameters.AddWithValue("@Invalid", form.Invalid);
                                cmd.ExecuteNonQuery();
                            }
                            conn.Close();

                            LoadFormalData();
                            dataGridView2.Rows[dataGridView2.Rows.GetLastRow(DataGridViewElementStates.None)].Selected = true;
                            dataGridView2.FirstDisplayedScrollingRowIndex = dataGridView2.Rows.GetLastRow(DataGridViewElementStates.None);
                        } // 批量 or 单个
                    } // 测试 or 正式
                } // using conn
            }
        }

        // 编辑
        private void btnEdit_Click(object sender, EventArgs e) {
            DataPropertyForm form = new DataPropertyForm();
            form.Mode = (tabControl1.SelectedIndex == 1 ? (int)FormMode.Test : (int)FormMode.Formal) | (int)FormMode.Edit;
            OleDbConnection conn = new OleDbConnection(Program.ConnectionString);

            if (tabControl1.SelectedIndex == 1) {
                // 测试
                OleDbCommand cmd = new OleDbCommand("SELECT * FROM Test WHERE Id=@Id", conn);
                cmd.Parameters.AddWithValue("@Id", dataGridView1.SelectedRows[0].Cells["testId"].Value.ToString());
                using (conn) {
                    conn.Open();
                    OleDbDataReader reader = cmd.ExecuteReader();
                    if (reader.Read()) {
                        form.PlateNumber = reader["PlateNumber"].ToString();
                        form.SubmitDate = reader["SubmitDate"] != System.DBNull.Value ? (DateTime)reader["SubmitDate"] : DateTime.MinValue.Date;
                        form.State = (int)reader["State"];
                        form.Invalid = (bool)reader["Invalid"];
                    }
                    conn.Close();
                }
            }
            else {
                // 正式
                OleDbCommand cmd = new OleDbCommand("SELECT * FROM Formal WHERE Id=@Id", conn);
                cmd.Parameters.AddWithValue("@Id", dataGridView2.SelectedRows[0].Cells["formalId"].Value.ToString());
                using (conn) {
                    conn.Open();
                    OleDbDataReader reader = cmd.ExecuteReader();
                    if (reader.Read()) {
                        form.VIN = reader["VIN"].ToString();
                        form.PlateNumber = reader["PlateNumber"].ToString();
                        form.CardType = reader["CardType"].ToString();
                        form.CardNo = reader["CardNo"].ToString();
                        form.SubmitDate = reader["SubmitDate"] != System.DBNull.Value ? (DateTime)reader["SubmitDate"] : DateTime.MinValue.Date;
                        form.State = (int)reader["State"];
                        form.Invalid = (bool)reader["Invalid"];
                    }
                    conn.Close();
                }
            }

            // 保存
            if (form.ShowDialog(this) == DialogResult.OK) {
                conn = new OleDbConnection(Program.ConnectionString);
                OleDbCommand cmd = null;
                if (tabControl1.SelectedIndex == 1) {
                    // 测试
                    cmd = new OleDbCommand("UPDATE Test SET PlateNumber=@PlateNumber, SubmitDate=@SubmitDate, State=@State, Invalid=@Invalid WHERE Id=@Id", conn);
                    cmd.Parameters.AddWithValue("@PlateNumber", form.PlateNumber);
                    if (form.SubmitDate != DateTime.MinValue.Date) {
                        cmd.Parameters.AddWithValue("@SubmitDate", form.SubmitDate);
                    }
                    else {
                        cmd.Parameters.AddWithValue("@SubmitDate", System.DBNull.Value);
                    }
                    cmd.Parameters.AddWithValue("@State", form.State);
                    cmd.Parameters.AddWithValue("@Invalid", form.Invalid);
                    cmd.Parameters.AddWithValue("@Id", dataGridView1.SelectedRows[0].Cells["testId"].Value.ToString());
                    using (conn) {
                        conn.Open();
                        cmd.ExecuteNonQuery();
                        conn.Close();
                    }

                    int index = dataGridView1.SelectedRows[0].Index;
                    LoadTestData();
                    dataGridView1.Rows[index].Selected = true;
                    dataGridView1.FirstDisplayedScrollingRowIndex = index;
                }
                else {
                    // 正式
                    cmd = new OleDbCommand("UPDATE Formal SET VIN=@VIN, PlateNumber=@PlateNumber, CardType=@CardType, CardNo=@CardNo, SubmitDate=@SubmitDate, State=@State, Invalid=@Invalid WHERE Id=@Id", conn);
                    cmd.Parameters.AddWithValue("@VIN", form.VIN);
                    cmd.Parameters.AddWithValue("@PlateNumber", form.PlateNumber);
                    cmd.Parameters.AddWithValue("@CardType", form.CardType);
                    cmd.Parameters.AddWithValue("@CardNo", form.CardNo);
                    if (form.SubmitDate != DateTime.MinValue.Date) {
                        cmd.Parameters.AddWithValue("@SubmitDate", form.SubmitDate);
                    }
                    else {
                        cmd.Parameters.AddWithValue("@SubmitDate", System.DBNull.Value);
                    }
                    cmd.Parameters.AddWithValue("@State", form.State);
                    cmd.Parameters.AddWithValue("@Invalid", form.Invalid);
                    cmd.Parameters.AddWithValue("@Id", dataGridView2.SelectedRows[0].Cells["formalId"].Value.ToString());
                    using (conn) {
                        conn.Open();
                        cmd.ExecuteNonQuery();
                        conn.Close();
                    }

                    int index = dataGridView2.SelectedRows[0].Index;
                    LoadFormalData();
                    dataGridView2.Rows[index].Selected = true;
                    dataGridView2.FirstDisplayedScrollingRowIndex = index;
                }
            }
        }

        // 删除
        private void btnDelete_Click(object sender, EventArgs e) {
            if (MessageBox.Show(this, "确定要删除吗？", Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) {
                return;
            }

            if (tabControl1.SelectedIndex == 1) {
                // 测试
                int selectedRowsCount = dataGridView1.SelectedRows.Count;
                int rowsCount = dataGridView1.Rows.Count;

                OleDbConnection conn = new OleDbConnection(Program.ConnectionString);
                using (conn) {
                    conn.Open();

                    OleDbCommand cmd = null;
                    foreach (DataGridViewRow row in dataGridView1.SelectedRows) {
                        cmd = new OleDbCommand("DELETE FROM Test WHERE Id=@Id", conn);
                        cmd.Parameters.AddWithValue("@Id", row.Cells["testId"].Value.ToString());
                        cmd.ExecuteNonQuery();
                    }

                    if (selectedRowsCount == rowsCount) {
                        cmd = new OleDbCommand("ALTER TABLE Test ALTER COLUMN [Id] COUNTER (1, 1)", conn);
                        cmd.ExecuteNonQuery();
                    }
                    conn.Close();
                }

                LoadTestData();
            }
            else {
                // 正式
                OleDbConnection conn = new OleDbConnection(Program.ConnectionString);
                using (conn) {
                    conn.Open();
                    foreach (DataGridViewRow row in dataGridView2.SelectedRows) {
                        OleDbCommand cmd = new OleDbCommand("DELETE FROM Formal WHERE Id=@Id", conn);
                        cmd.Parameters.AddWithValue("@Id", row.Cells["formalId"].Value.ToString());
                        cmd.ExecuteNonQuery();
                    }
                    conn.Close();
                }

                LoadFormalData();
            }
        }

        // 关闭
        private void btnClose_Click(object sender, EventArgs e) {
            Close();
        }

        private void UpdateUI() {
            if (tabControl1.SelectedIndex == 1) {
                // 测试
                btnEdit.Enabled = dataGridView1.SelectedRows.Count == 1;
                btnDelete.Enabled = dataGridView1.SelectedRows.Count > 0;
            }
            else {
                // 正式
                btnEdit.Enabled = dataGridView2.SelectedRows.Count == 1;
                btnDelete.Enabled = dataGridView2.SelectedRows.Count > 0;
            }
        }

        // 刷新
        private void btnRefresh_Click(object sender, EventArgs e) {
            LoadTestData();
            LoadFormalData();
        }

        //// 批量生成
        //private void btnBatch_Click(object sender, EventArgs e) {
        //    TestRangeForm form = new TestRangeForm();
        //    if (form.ShowDialog(this) == DialogResult.OK) {
        //        Cursor = Cursors.WaitCursor;

        //        OleDbConnection conn = new OleDbConnection(Program.ConnectionString);
        //        using (conn) {
        //            conn.Open();
        //            foreach (string number in form.Numbers) {
        //                OleDbCommand cmd = new OleDbCommand("INSERT INTO Test(PlateNumber, SubmitDate, State, Invalid) VALUES(@PlateNumber, @SubmitDate, @State, @Invalid)", conn);
        //                cmd.Parameters.AddWithValue("@PlateNumber", number);
        //                cmd.Parameters.AddWithValue("@SubmitDate", System.DBNull.Value);
        //                cmd.Parameters.AddWithValue("@State", 0);
        //                cmd.Parameters.AddWithValue("@Invalid", false);
        //                cmd.ExecuteNonQuery();
        //                Thread.Sleep(50);
        //            }
        //        }

        //        btnRefresh.PerformClick();
        //        dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.Rows.Count - 1;

        //        Cursor = Cursors.Default;
        //    }
        //}
    }
}
